home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
11587
/
11587.xpi
/
chrome
/
aviary.jar
/
content
/
upload.js
< prev
next >
Wrap
Text File
|
2009-07-09
|
12KB
|
353 lines
/* Copyright (c) 2007-2009 Pearl Crescent, LLC. All Rights Reserved. */
/* vim: set sw=2 sts=2 ts=8 et syntax=javascript: */
var gAviaryUpload =
{
// If aOpenWithToolID is not zero, image is opened in app after uploading.
// aInputStream must be an nsIBinaryInputStream.
UploadStream: function(aContentType, aInputStream, aFileName, aOriginatingURL,
aProgressMeter, aOpenWithToolID)
{
if (!aContentType || !aInputStream)
{
throw new Components.Exception("missing parameter",
Components.results.NS_ERROR_INVALID_ARG);
}
if (aProgressMeter && aProgressMeter.IsCanceled())
{
aProgressMeter.Close(false, null);
return;
}
var uploader = new AviaryFileUploader(aContentType, aInputStream, null,
aFileName, aOriginatingURL,
aProgressMeter, aOpenWithToolID);
},
// If aOpenWithToolID is not zero, image is opened in app after uploading.
UploadByURL: function(aImageURL, aOpenWithToolID)
{
if (!aImageURL)
{
throw new Components.Exception("missing parameter",
Components.results.NS_ERROR_INVALID_ARG);
}
var uploader = new AviaryFileUploader(null, null, aImageURL, null, null,
null, aOpenWithToolID);
},
endOfObject: true
};
// It would be better to nest this within gAviaryUpload.
function AviaryFileUploader(aContentType, aInputStream, aImageURL, aFileName,
aOriginatingURL, aProgressMeter, aOpenWithToolID)
{
this.init(aContentType, aInputStream, aImageURL, aFileName, aOriginatingURL,
aProgressMeter, aOpenWithToolID);
}
AviaryFileUploader.prototype =
{
kUploadDestURL: "",
kFileDetailsURL: "",
kUploadDestURLSuffix: "/apps/xmlapi/receiver.aspx",
kFileDetailsURLSuffix: "/creation?fguid=",
kUploadSource: "upload",
kUploadAUID: "aviaryframework",
kUploadAndEditAUID: "aviarysourcefile",
kMIMEBoundaryPrefix: "--------AVIARY_",
kEndOfLineStr: "\r\n",
mPearlUtil: null,
mOpenWithToolID: 0,
mRequest: null,
mRequestHasBeenAborted: false,
mMIMEBoundary: null,
mProgressMeter: null,
init: function(aContentType, aInputStream, aImageURL, aFileName,
aOriginatingURL, aProgressMeter, aOpenWithToolID)
{
if (!aImageURL && (!aContentType || !aInputStream))
{
throw new Components.Exception("missing parameter",
Components.results.NS_ERROR_INVALID_ARG);
}
this.mPearlUtil = com.aviary.talon.pearlutil;
this.mProgressMeter = aProgressMeter;
this.mOpenWithToolID = aOpenWithToolID;
this.mMIMEBoundary = this.kMIMEBoundaryPrefix + Math.random();
var serverPrefix = this.mPearlUtil.GetASCIIPref("aviary.serverPrefix");
if (serverPrefix)
{
this.kUploadDestURL = serverPrefix + this.kUploadDestURLSuffix;
this.kFileDetailsURL = serverPrefix + this.kFileDetailsURLSuffix;
}
// this.kUploadDestURL = "http://quartz/dist/aviary/upload/";
if (aProgressMeter)
{
var str = this.mPearlUtil.GetLocalizedString("SAVING_TO_ROOKERY");
aProgressMeter.SetLabel(str);
var self = this;
aProgressMeter.SetCancelFunction(function() { self.OnCancel(); });
}
if (!aImageURL)
{
if (!aFileName)
{
// Use default file name. Determine extension based on content type.
var fileExt = "";
if ("image/png" == aContentType)
fileExt = ".png";
else if ("image/jpg" == aContentType)
fileExt = ".jpg";
else if ("image/gif" == aContentType)
fileExt = ".gif";
aFileName = this.mPearlUtil
.GetLocalizedString("SUGGESTED_FILE_PREFIX") + fileExt;
}
if (aProgressMeter)
aProgressMeter.SetName(aFileName);
}
// Create and initialize request.
this.mRequest = new XMLHttpRequest();
var self = this;
this.mRequest.onload = function() { self.onLoad(self); }
this.mRequest.onerror = function() { self.onError(self); }
this.mRequest.onuploadprogress =
function(aEvent) { self.onUploadProgress(self, aEvent); }
this.mRequest.open("POST", this.kUploadDestURL, true);
com.aviary.talon.request.
EnsureCookiesWillBeSent(this.mRequest.channel, null);
this.mRequest.setRequestHeader("Content-type",
"multipart/form-data; boundary=" + this.mMIMEBoundary);
this.mRequest.overrideMimeType("application/xml");
// Arrange to send a file upload form post.
const kMSCID = "@mozilla.org/io/multiplex-input-stream;1";
var multiStream = Components.classes[kMSCID]
.createInstance(Components.interfaces.nsIMultiplexInputStream);
var s = this.createInputStringBodyPart("source", this.kUploadSource);
var auid = (0 != this.mOpenWithToolID) ? this.kUploadAndEditAUID
: this.kUploadAUID;
s += this.createInputStringBodyPart("auid", auid);
multiStream.appendStream(this.createStringStream(s));
var endOfMIMESuffix = "";
if (aImageURL)
{
// To cause an error, use s += on next line.
s = this.createInputStringBodyPart("url", aImageURL);
multiStream.appendStream(this.createStringStream(s));
}
else
{
if (aOriginatingURL)
{
s = this.createInputStringBodyPart("originalurl", aOriginatingURL);
multiStream.appendStream(this.createStringStream(s));
}
var filePrefix = "--" + this.mMIMEBoundary + this.kEndOfLineStr
+ "Content-Disposition: form-data; name=\"file\"; "
+ "filename=\"" + aFileName + "\"" + this.kEndOfLineStr
+ "Content-type: " + aContentType + this.kEndOfLineStr
+ this.kEndOfLineStr;
multiStream.appendStream(this.createStringStream(filePrefix));
/*
* Ensure that the image stream is seekable (required by NoScript and
* possibly by Necko).
*/
var storageStream = Components.classes["@mozilla.org/storagestream;1"]
.createInstance(Components.interfaces.nsIStorageStream);
storageStream.init(32768, -1, null);
var outputStream = storageStream.getOutputStream(0);
const kMaxBlockSize = 65536;
var remaining = aInputStream.available();
while (remaining > 0)
{
var count = (remaining > kMaxBlockSize) ? kMaxBlockSize : remaining;
var b = aInputStream.readBytes(count);
outputStream.write(b, count);
remaining -= count;
}
outputStream.close();
multiStream.appendStream(storageStream.newInputStream(0));
endOfMIMESuffix += this.kEndOfLineStr;
}
endOfMIMESuffix += "--" + this.mMIMEBoundary + this.kEndOfLineStr;
multiStream.appendStream(this.createStringStream(endOfMIMESuffix));
this.mRequest.send(multiStream);
},
onUploadProgress: function(aThisObj, aEvent)
{
var percentDone = Math.floor(100 * (aEvent.position / aEvent.totalSize));
if (percentDone > 100)
percentDone = 100; // TODO: position exceeds totalSize; FF bug??
// dump("onUploadProgress: " + percentDone + "% of " + aEvent.totalSize + "\n");
if (aThisObj.mProgressMeter)
aThisObj.mProgressMeter.SetValue(percentDone);
},
onLoad: function(aThisObj)
{
if (aThisObj.mRequestHasBeenAborted)
return;
if (aThisObj.mProgressMeter)
aThisObj.mProgressMeter.SetIsCancelable(false); // Too late to cancel.
var succeeded = false;
try {
const knsIHttpChannel = Components.interfaces.nsIHttpChannel;
var channel = aThisObj.mRequest.channel.QueryInterface(knsIHttpChannel);
succeeded = channel.requestSucceeded;
} catch(e) { dump("onLoad: " + e + "\n"); }
// dump("response text:\n" + aThisObj.mRequest.responseText + "\n");
var fguid = null;
if (succeeded)
{
succeeded = false;
var responseNode = aThisObj.getResponseNode(aThisObj.mRequest);
if (responseNode)
{
var fileNode = aThisObj.mPearlUtil
.PearlGetFirstElementByTagName(responseNode, "file");
if (fileNode)
{
fguid = aThisObj.mPearlUtil.GetFirstChildText(fileNode, "fileguid");
succeeded = (fguid != null && fguid.length > 0);
}
}
}
if (!succeeded)
{
aThisObj.onError(aThisObj);
return;
}
if (aThisObj.mProgressMeter)
{
aThisObj.mProgressMeter.SetValue(100);
aThisObj.mProgressMeter.Close(true, "IMAGE_SAVED"); // fade out
}
if (0 != aThisObj.mOpenWithToolID)
{
gAviaryMain.LaunchAppByToolID(aThisObj.mOpenWithToolID, fguid,
null, null);
}
else
{
var detailsURL = this.kFileDetailsURL + encodeURIComponent(fguid);
gAviaryMain.OpenInNewTab(detailsURL, null);
}
},
onError: function(aThisObj)
{
if (aThisObj.mProgressMeter)
aThisObj.mProgressMeter.Close(false, null); // close immediately
if (aThisObj.mRequestHasBeenAborted) // Suppress errors if canceled.
return;
// If possible, get detailed information from <failedfiles> within response.
var errMsg;
var responseNode = aThisObj.getResponseNode(aThisObj.mRequest);
if (responseNode)
{
var node = aThisObj.mPearlUtil
.PearlGetFirstElementByTagName(responseNode, "failedfile");
if (node)
{
errMsg = aThisObj.mPearlUtil.GetNodeText(node);
if (!errMsg)
errMsg = node.getAttribute("reason");
}
}
// TODO: fit this error message within a caller-provider message.
if (!errMsg)
errMsg = "Upload failed."; // TODO: L10n
aThisObj.mPearlUtil.Alert(window, errMsg);
},
OnCancel: function()
{
this.mRequestHasBeenAborted = true;
if (this.mProgressMeter)
{
this.mProgressMeter.Close(false, null); // close immediately
this.mProgressMeter = null;
}
if (this.mRequest)
this.mRequest.abort();
},
getResponseNode: function(aRequest)
{
var responseNode = null;
if (aRequest && aRequest.responseXML)
{
var responseDoc = aRequest.responseXML;
if (responseDoc && responseDoc.firstChild &&
responseDoc.firstChild.nodeName == "response")
{
responseNode = responseDoc.firstChild;
}
}
return responseNode;
},
createStringStream: function(aStr)
{
if (!aStr)
return null;
const kSISCID = "@mozilla.org/io/string-input-stream;1";
var strStream = Components.classes[kSISCID]
.createInstance(Components.interfaces.nsIStringInputStream);
strStream.setData(aStr, aStr.length);
return strStream;
},
createInputStringBodyPart: function(aName, aValue)
{
if (!aName || !aValue)
return "";
var s = "--" + this.mMIMEBoundary + this.kEndOfLineStr
+ "Content-Disposition: form-data; name=\"" + aName + "\""
+ this.kEndOfLineStr + this.kEndOfLineStr;
s += aValue + this.kEndOfLineStr;
return s;
},
endOfObject: true
}